package cn.miao.simple;

import com.rabbitmq.client.*;
import com.rabbitmq.client.impl.AMQImpl;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @program: QuickStart-RabbitMQ
 * @description: 消费者
 * @author: MiaoWei
 * @create: 2021-10-19 18:28
 **/
public class Consumer {
    public static void main(String[] args) {
        //所有的中间件技术都是基于tcp/ip协议基础之上构建新型的协议规范,只不过rabbitMQ遵循的是AMQP协议
        //为什么有AMQP协议:就是因为TCP/IP协议无法去满足它的一些规范,比如我要把这消息的一些标签,通道,都要把它记录起来,这个TCP/IP就无法满足了!

        //1.创建连接工程
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
//        connectionFactory.setVirtualHost("/");  //把消息发在我们的根节点上

        Connection connection = null;
        Channel channel = null;
        try {
            //2.创建连接Connection
            connection = connectionFactory.newConnection("生成者");
            //3.通过连接获取通道channel
            channel = connection.createChannel();
            //4.通过通道创建交换机,声明队列,绑定关系,路由key,发送消息和接收消息
            //这里表示从`queue1`这个队列里面取-----------可以理解为监听队列
//            channel.basicConsume("queue1", true, new DeliverCallback() {
//                @Override
//                public void handle(String s, Delivery delivery) throws IOException {
//                    System.out.println("收到消息是 " + new String(delivery.getBody(), StandardCharsets.UTF_8));
//                }
//                //这里是出现异常的状况,比如接收消息失败! 回调
//            }, new CancelCallback() {
//                @Override
//                public void handle(String s) throws IOException {
//                    //出现异常的状况
//                    System.out.println("接收消息失败!");
//                }
//            });

            //测试
            Channel finalChannel = channel;
            com.rabbitmq.client.Consumer consumer = new DefaultConsumer(finalChannel){
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    System.out.println("consumerTag = " + consumerTag);
                    System.out.println("获取交换机 = " + envelope.getExchange());
                    System.out.println("获取路由key = " + envelope.getRoutingKey());
                    System.out.println("获取消息的id = " + envelope.getDeliveryTag());
                    System.out.println("获取其他属性 = " + properties.getHeaders());
                    System.out.println("获取消息主体 = " + new String(body));
                    //手动应答
                    finalChannel.basicAck(envelope.getDeliveryTag(), false);
                }
            };
            channel.basicConsume("queue1",false, consumer);



            System.out.println("开始接收消息");
            //这里我不让程序往下执行,进行阻断
            System.in.read();

            System.out.println("消息发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //7.关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            //8.关闭连接
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
